package com.trimer.rpc.proxy;

import com.trimer.rpc.core.request.RpcRequest;
import com.trimer.rpc.core.response.RpcResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;

@Component
public class RpcInvoker {

    private RestTemplate restTemplate;
    @Autowired
    private Environment environment;


    @SuppressWarnings("unchecked")
    public <T> T createBean(final Class<?> interfaceClass, final String serviceVersion) {
        ClassLoader classLoader = interfaceClass.getClassLoader();
        Class<?>[] interfaces = {interfaceClass};
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //创建RPC请求
                RpcRequest request = new RpcRequest();
                request.setSid(UUID.randomUUID().toString());
                request.setServiceName(method.getDeclaringClass().getName());
                request.setServiceVersion(serviceVersion);
                request.setMethodName(method.getName());
                request.setParamTypes(method.getParameterTypes());
                request.setParams(args);

                RpcResponse response = invokeProcessHandler(request);
                if (response == null) {
                    throw new RuntimeException("Response is null");
                }

                return response.getResult();
            }
        };
        return (T) Proxy.newProxyInstance(classLoader, interfaces, invocationHandler);
    }

    private RpcResponse invokeProcessHandler(RpcRequest request) throws Exception {
        restTemplate = new RestTemplate();
        String rpcserver = environment.getProperty("rpcserver");
        ResponseEntity<RpcResponse> responseEntity = restTemplate.postForEntity(rpcserver, request, RpcResponse.class);
        RpcResponse response = responseEntity.getBody();
        return response;
    }

}